package com.yejiali.backend.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.yejiali.backend.common.annotaion.SystemLog;
import com.yejiali.backend.common.httpcode.HttpCodeEnum;
import com.yejiali.backend.entity.MyUserDetails;
import com.yejiali.backend.entity.dto.LoginRequestDTO;
import com.yejiali.backend.entity.dto.LoginDTO;
import com.yejiali.backend.entity.vo.UserInfoVO;
import com.yejiali.backend.exception.SystemException;
import com.yejiali.backend.response.Response;
import com.yejiali.backend.service.LoginService;
import com.yejiali.backend.service.UserService;
import com.yejiali.backend.utils.JwtTokenUtil;
import com.yejiali.backend.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @Author:yejiali
 * @Date:2025/5/14-05-14-14:55
 * @Decsription:com.yejiali.backend.service.impl
 * @Version:1.0
 */
@Service
public class LoginServiceImpl implements LoginService {
    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private UserService userService;

    @Override
    @SystemLog("登录接口")
    public Response login(LoginRequestDTO requestDTO) {
        //封装认证对象
        Authentication authentication = new UsernamePasswordAuthenticationToken(requestDTO.getUsername(), requestDTO.getPassword());
        //进行认证
        Authentication authenticate = authenticationManager.authenticate(authentication);
        //判断是否校验成功
        if(Objects.isNull(authenticate)){
            throw new SystemException(HttpCodeEnum.LOGIN_ERROR);
        }
        //获取用户信息
        MyUserDetails myUserDetails = (MyUserDetails) authenticate.getPrincipal();
        //获取用户id
        Long userId = myUserDetails.getUser().getId();
        //获取用户名
        String username = myUserDetails.getUsername();
        //认证成功,userId和角色生成token
        Map<String, Object> claims = new HashMap<>();
        claims.put("userId",userId.toString());
        String token= jwtTokenUtil.generateToken(claims,username);
        //储存用户信息到redis中
        redisUtil.set("user:"+userId,myUserDetails);
        //更新登录时间
        userService.updateLoginTime(userId);
        //分装返回信息
        UserInfoVO userInfoVO = BeanUtil.copyProperties(myUserDetails.getUser(), UserInfoVO.class);
        //设置角色  // TODO 暂时写死(这里默认每个账户只有一个固定角色）
        String role = myUserDetails.getAuthorities().iterator().next().getAuthority();
        userInfoVO.setRole(role);
        LoginDTO loginDTO = new LoginDTO(token, userInfoVO);
        return Response.success(loginDTO);

    }

    /**
     * 退出登录
     * @return
     */
    @Override
    @SystemLog("退出登录")
    public Response logout() {
        try {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            if (authentication != null) {
                MyUserDetails myUserDetails = (MyUserDetails) authentication.getPrincipal();
                Long userId = myUserDetails.getUser().getId();
                // 清除redis中的数据
                redisUtil.del("user:" + userId);
                // 清除上下文数据
                SecurityContextHolder.clearContext();
            }
            return Response.success("退出成功");
        } catch (AccessDeniedException e) {
            return Response.error(HttpCodeEnum.NO_OPERATOR_AUTH.getCode(), "无权限操作");
        } catch (Exception e) {
            throw new RuntimeException("退出失败", e);
        }
    }
}
